//
// Created by 11510 on 2024/7/10.
//

#ifndef REACTOR_V4_EVENTFD_H
#define REACTOR_V4_EVENTFD_H

#include <sys/eventfd.h>
#include <unistd.h>
#include <poll.h>
#include <functional>

class EventFd {
public:
    using EventFdCallback = std::function<void()>;
private:
    int _evtfd;
    EventFdCallback _cb;
    bool _isStarted;


public:
    EventFd(EventFdCallback &&cb) :
            _evtfd(createEventfd()),
            _cb(std::move(cb)),
            _isStarted(false) {}

    ~EventFd() = default;

    void start() {
        struct pollfd pfd;
        pfd.fd = _evtfd;
        pfd.events = POLLIN;

        _isStarted = true;
        while (_isStarted) {
            int nready = poll(&pfd, 1, 5000);
            if (-1 == nready && errno == EINTR) {
                continue;
            } else if (-1 == nready) {
                perror("-1 == nready");
            } else if (0 == nready) {
                perror("0 == nready");
            } else {
                if (pfd.revents & POLLIN) {
                    handleRead();
                    if (_cb) {
                        _cb();
                    }
                }

            }

        }
    }

    void stop() {
        _isStarted = false;
    }

    int createEventfd() {
        int ret = eventfd(10, 0);
        if (ret < 0) {
            perror("eventfd");
            return ret;
        }
        return ret;
    }

    void handleRead() {
//        需要赋初值1 ???
        uint64_t one;
        ssize_t ret = read(_evtfd, &one, sizeof one);
        if (ret != sizeof one) {
            perror("read");
            return;
        }
    }

    void wakeup() {
        uint64_t one = 1;
        ssize_t ret = write(_evtfd, &one, sizeof one);
        if (ret != sizeof one) {
            perror("write");
            return;
        }
    }

};


#endif //REACTOR_V4_EVENTFD_H
